package com.fish.service.impl.passport;

import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.fish.common.constant.Constant;
import com.fish.common.constant.QueryPage;
import com.fish.passport.dao.PassCodeDAO;
import com.fish.passport.dao.PassEventDAO;
import com.fish.passport.dao.PassPortCodeDAO;
import com.fish.passport.po.PassCode;
import com.fish.passport.po.PassEvent;
import com.fish.passport.po.PassPortCode;
import com.fish.passport.po.Template;
import com.fish.passport.processor.ApplyCodeProcessor;
import com.fish.passport.processor.DestroyCodeProcessor;
import com.fish.passport.processor.Processor;
import com.fish.passport.processor.ProcessorFactory;
import com.fish.passport.processor.ResendCodeProcessor;
import com.fish.passport.processor.UpdateContactProcessor;
import com.fish.passport.processor.UpdateContentProcessor;
import com.fish.service.passport.PassCodeService;
import com.fish.vo.Passport;
import com.fish.vo.PassportConstant;

/**
 * @author ShiHui
 */
public class PassCodeServiceImpl implements PassCodeService {
	private static final Log log = LogFactory.getLog(PassCodeServiceImpl.class);
	
	private PassCodeDAO passCodeDAO;
	private PassPortCodeDAO passPortCodeDAO;
	private PassEventDAO passEventDAO;
	
	private ApplyCodeProcessorCallbackServiceImpl applyCodeProcessorCallbackService;
	private DestroyCodeProcessorCallbackServiceImpl destroyCodeProcessorCallbackService;
	private ResendCodeProcessorCallbackServiceImpl resendCodeProcessorCallbackService;
	private UpdateContactProcessorCallbackServiceImpl updateContactProcessorCallbackService;
	private UpdateContentProcessorCallbackServiceImpl updateContentProcessorCallbackService;

	/**
	 * 添加通关码信息
	 */
	public String addPassCode(PassCode passCode) {
		return passCodeDAO.addPassCode(passCode);
	}

	public void deletePassCode(String codeId) {
		passCodeDAO.deletePassCode(codeId);
	}

	/**
	 * 如果选择了通关点条件，进行关联查询，否则进行单表查询
	 * 
	 * @param 查询条件
	 */
	public List<PassCode> queryPassCodes( PassCode passCode) {
		return passCodeDAO.selectByParams(passCode);
	}

	/**
	 * 查询通关点信息记录数
	 * 
	 * @param params
	 * @return
	 */
	public Integer selectRowCount(PassCode passCode) {
		return this.passCodeDAO.selectRowCount(passCode);
	}

	/**
	 * 通过申请流水号查询通关码信息
	 * 
	 * @param 查询参数
	 */
	public PassCode getCodeBySerialNo(String SerialNo) {
		return this.passCodeDAO.getCodeBySerialNo(SerialNo);
	}

	public void updatePassCode(PassCode passCode) {
		passCodeDAO.updatePassCode(passCode);
	}

	public boolean onApply(String codeId) {
		PassCode passCode = this.passCodeDAO.getPassCodeByCodeId(codeId);
		log.info("if passCode entry exists: " + (passCode==null));
		if (passCode != null && !passCode.isApplySuccess()) {
			log.info("passCode codeId=" + passCode.getCodeId());
			List<PassPortCode> passPortList = this.passPortCodeDAO.queryProviderByCode(passCode.getCodeId());
			passCode.setPassPortList(passPortList);
			ApplyCodeProcessor applyCodeProcessor = (ApplyCodeProcessor)ProcessorFactory.create(passCode);
			if (applyCodeProcessor != null) {
				Passport passport = null;
				if (Constant.isActualApplyPassCode()) {
					passport = applyCodeProcessor.apply(passCode);
				} else {
					passport = mockApplyPassCode(passCode);
				}
				return this.applyCodeProcessorCallbackService.callback(passCode, passport, null);
			}
		}
		return false;
	}
	
	private Passport mockApplyPassCode(PassCode passCode) {
		Passport passport=new Passport();
		passport.setSerialno(passCode.getSerialNo());
		passport.setCode("1234567890");
		passport.setAddCode("1234567890");
		passport.setErrorNO(PassportConstant.PASSCODE_ERROR.APPLY.name());
		passport.setSendSms(PassportConstant.PASSCODE_SMS_SENDER.LVMAMA.name());
		passport.setSendOrderid(true);
		passport.setEventType(PassportConstant.PASSCODE_TYPE.APPLAYCODE.name());
		passport.setStatus(PassportConstant.PASSCODE_STATUS.SUCCESS.name());
		passport.setExtId(passCode.getSerialNo());
		return passport;
	}
	
	public boolean onEvent(String eventId) {
		PassEvent event = passEventDAO.selectByEventId(eventId);
		if (event!=null) {
			PassCode passCode = passCodeDAO.getCodeByEventId(eventId);
			if (passCode!=null) {
				List<PassPortCode> passPortList = passPortCodeDAO.queryProviderByCode(passCode.getCodeId());
				passCode.setPassPortList(passPortList);
				return doCallbackProcessorByEvent(event, passCode);
			}
		}
		return false;
	}
	
	private boolean doCallbackProcessorByEvent(PassEvent passEvent, PassCode passCode) {
		// 废码回调
		if (passEvent.isDestroyCodeEvent()) {
			Processor pro=ProcessorFactory.create(passCode);
			if(pro instanceof DestroyCodeProcessor){
				DestroyCodeProcessor destroyCodeProcessor = (DestroyCodeProcessor)pro;
				Passport passport = destroyCodeProcessor.destroy(passCode);
				return this.destroyCodeProcessorCallbackService.callback(passCode, passport, passEvent);
			}
		// 更新内容回调
		}  else if (passEvent.isUpdateContentEvent()) {
			Processor pro = ProcessorFactory.create(passCode);
			
			if(pro instanceof UpdateContentProcessor){
				UpdateContentProcessor updateContentProcessor = (UpdateContentProcessor)pro;
				Passport passport = updateContentProcessor.update(passCode);
				return this.updateContentProcessorCallbackService.callback(passCode, passport, passEvent);
			}
			
		// 重发短信回调
		} else if (passEvent.isResendEvent()) {
			if (passCode.isSendSmsByPartner()) {
				Processor pro=ProcessorFactory.create(passCode);
				if(pro instanceof ResendCodeProcessor){
					ResendCodeProcessor resendCodeProcessor = (ResendCodeProcessor)pro;
					Passport passport = resendCodeProcessor.resend(passCode);
					return this.resendCodeProcessorCallbackService.callback(passCode, passport, passEvent);
				}
			}
		//更新订单联系人
		} else if (passEvent.isUpdateContactEvent()) {
			Processor pro=ProcessorFactory.create(passCode);
			if(pro instanceof UpdateContactProcessor){
				UpdateContactProcessor updateContactProcessor = (UpdateContactProcessor)pro;
				Passport passport = updateContactProcessor.update(passCode);
				return this.updateContactProcessorCallbackService.callback(passCode, passport, passEvent);
			}
		}
		return false;
	}
	
	/**
	 * 查询通关点的提供商信息
	 * 
	 * @author clj
	 * @param codeId
	 * 
	 * @return
	 */
	public List<PassPortCode> queryProviderByCode(String codeId) {
		return this.passPortCodeDAO.queryProviderByCode(codeId);
	}

	/**
	 * 生成申请流水号
	 * 
	 * @return
	 */
	public Long getSerialNo() {
		return this.passCodeDAO.getSerialNo();
	}

	/**
	 * 通过服务商和游玩日期查询通关点信息
	 * 
	 * @param params
	 * @return
	 */

	public List<PassCode> selectCodeByProviderIdAndValidTime(Map<String,Object> params){
		List<PassCode> passCodeList= this.passCodeDAO.selectCodeByProviderIdAndValidTime(params);
		for(PassCode passCode:passCodeList){
			List<PassPortCode> passPortList = this.passPortCodeDAO.queryProviderByCode(passCode.getCodeId());
			passCode.setPassPortList(passPortList);
		}
		return passCodeList;
		 
	}
	/**
	 * 通过模板代码查询模板信息
	 * 
	 * @param templateCode
	 * @return
	 */
	public Template selectTemplateByCode(String templateCode){
		return this.passCodeDAO.selectTemplateByCode(templateCode);
	}
	/**
	 * 通过组合参数查询通关码信息
	 * 
	 * @param 查询参数
	 */
	public PassCode getPassCodeByParams(Map<String, Object> params ) {
		 return this.passCodeDAO.getPassCodeByParams(params);
	}
	/**
	 * 查询订单是否已经履行
	 * @param params
	 * @return
	 */
	public boolean hasPerform(Map<String, Object> params ){
		return this.passCodeDAO.hasPerform(params);
	}
	
	/**
	 * 通过辅助码MD5编号查询通关码信息
	 * 
	 * @param 查询参数
	 */
	public PassCode getCodeByAddCodeMd5(String addCodeMd5){
		return this.passCodeDAO.getCodeByAddCodeMd5(addCodeMd5);
	}
	
	/**
	 * 查询离线模式通关信息列表
	 * @param params
	 * @return
	 */
	public List<PassCode> selectVouchersByProviderId(Map<String,Object> params){
		return this.passCodeDAO.selectVouchersByProviderId(params);
	}
	
	/**
	 * 通过通关点编号查询通关点关联信息
	 * 
	 * @param CodeId
	 * @return
	 */
	public List<PassPortCode> searchPassPortByCodeId(String codeId) {
		return this.passPortCodeDAO.searchPassPortByCodeId(codeId);
	}
	
	public void setPassEventDAO(PassEventDAO passEventDAO) {
		this.passEventDAO = passEventDAO;
	}

	public void setPassCodeDAO(PassCodeDAO passCodeDAO) {
		this.passCodeDAO = passCodeDAO;
	}

	public void setPassPortCodeDAO(PassPortCodeDAO passPortCodeDAO) {
		this.passPortCodeDAO = passPortCodeDAO;
	}

	@Override
	public Integer getSyncUpdatePassCodeCount(Map<String, Object> queryOption) {
		return passCodeDAO.getSyncUpdatePassCodeCount(queryOption);
	}

	@Override
	public Integer getUpdatePassCodeByCodeId(Map<String, Object> queryOption) {
		return passCodeDAO.getUpdatePassCodeByCodeId(queryOption);
	}

	@Override
	public Integer getUpdatePassCodeBySerId(Map<String, Object> queryOption) {
		return passCodeDAO.getUpdatePassCodeBySerId(queryOption);
	}

	public void setApplyCodeProcessorCallbackService(ApplyCodeProcessorCallbackServiceImpl applyCodeProcessorCallbackService) {
		this.applyCodeProcessorCallbackService = applyCodeProcessorCallbackService;
	}

	public void setDestroyCodeProcessorCallbackService(DestroyCodeProcessorCallbackServiceImpl destroyCodeProcessorCallbackService) {
		this.destroyCodeProcessorCallbackService = destroyCodeProcessorCallbackService;
	}

	public void setResendCodeProcessorCallbackService(ResendCodeProcessorCallbackServiceImpl resendCodeProcessorCallbackService) {
		this.resendCodeProcessorCallbackService = resendCodeProcessorCallbackService;
	}

	public void setUpdateContactProcessorCallbackService(UpdateContactProcessorCallbackServiceImpl updateContactProcessorCallbackService) {
		this.updateContactProcessorCallbackService = updateContactProcessorCallbackService;
	}

	public void setUpdateContentProcessorCallbackService(UpdateContentProcessorCallbackServiceImpl updateContentProcessorCallbackService) {
		this.updateContentProcessorCallbackService = updateContentProcessorCallbackService;
	}

	@Override
	public List<PassPortCode> queryProviderByCode(Long codeId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Long queryPassCodeCountByObject(PassCode passCode) {
		return this.passCodeDAO.queryPassCodeCountByObject(passCode);
	}

	@Override
	public List<PassCode> queryPassCodeByObject(PassCode passCode, QueryPage queryPage) {
		return this.passCodeDAO.queryPassCodeObject(passCode,queryPage);
	}
}
